﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.IO;
using System.Management;
using Microsoft.Win32;
using System.Diagnostics;
using System.Security.Principal;

namespace MegaSetting
{
    public partial class frmMainNeo : Form
    {


        private string strCurrentAccountName;
        private string strCurrentAccountSID;
        private string strAdminAccountSID;

        private bool boolIsFirstRun;


        public frmMainNeo()
        {
            InitializeComponent();
        }


        private void frmMainNeo_Load(object sender, EventArgs e)
        {
            comboDistricts.DataSource = Utility.GetDistricts();
            comboDistrictsMain.DataSource = Utility.GetDistricts();
            radioDistricts_CheckedChanged(sender, e);
            radioPoints_CheckedChanged(sender, e);

            GetEnvironments();
            LoadLocalSettings();


            

            if (!boolIsFirstRun)
            {
                btnStart.Enabled = true;
                btnStart_Click(this, e);
                panelPointSetting.Visible = true;
                labPointSetting.Text =
                    "网点代码：" + Utility.Setting.PointCode +
                    "\r\n 本机属性：" + (Utility.Setting.IsDatabase ? "数据库" : "") + "\t" + (Utility.Setting.IsManager ? "管理机" : "") +
                    "\r\n\r\n本机IP：" + Utility.Setting.LocalIp +
                    "\r\n子网掩码：" + Utility.Setting.SubMask +
                    "\r\n网关：" + Utility.Setting.GateWay +
                    "\r\n\r\n本地数据库：" + Utility.Setting.DatabaseIP +
                    "\r\n\r\n中心服务器：" + Utility.Setting.AppServerIP +
                    "\r\n更新服务器" + Utility.Setting.UpdateServerIP +
                    "\r\nGetoo服务器:" + Utility.Setting.GetooServerIP;
            }
        }


        private void radioDistricts_CheckedChanged(object sender, EventArgs e)
        {
            //dataGridView1.AllowUserToAddRows = false; 

            dataGridView1.DataSource = Utility.GetDistricts();
        }



        private void radioPoints_CheckedChanged(object sender, EventArgs e)
        {
            //dataGridView1.AllowUserToAddRows = true;

            comboDistricts.Enabled = radioPoints.Checked;

            dataGridView1.DataSource = Utility.GetPointsByDistrictId((int)comboDistricts.SelectedValue);


        }

        private void radioServers_CheckedChanged(object sender, EventArgs e)
        {
            //dataGridView1.AllowUserToAddRows = false;

            dataGridView1.DataSource = Utility.GetServers();
        }

        private void frmMainNeo_FormClosing(object sender, FormClosingEventArgs e)
        {
            Utility.SaveToDatabse();
        }

        private void comboDistricts_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!radioDistricts.Checked)
            {
                dataGridView1.DataSource = Utility.GetPointsByDistrictId((int)comboDistricts.SelectedValue);
            }
            
        }

        private void comboDistrictsMain_SelectedIndexChanged(object sender, EventArgs e)
        {
            comboPoint.DataSource = Utility.GetPointsByDistrictId((int)comboDistrictsMain.SelectedValue);
            txtGetooUrl.Text =Utility.GetDistricts()[(int)comboDistrictsMain.SelectedValue-1].GetooUrl;
        }

        private void comboPoint_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboPoint.SelectedValue != null)
            {
                txtPointCode.Text = comboPoint.SelectedValue.ToString();
            }

        }

        private void chkDatabase_CheckedChanged(object sender, EventArgs e)
        {

            txtDatabaseIP.Enabled = !chkDatabase.Checked;
            txtPointCode.Enabled = chkDatabase.Checked;
            if (chkDatabase.Checked)
            {

                chkManager.Checked = true;
            }

            txtDatabaseIP.Text = txtIPMain.Text + '.' + txtIPLast.Text;
        }

        private void txtPointCode_TextChanged(object sender, EventArgs e)
        {
            string gateWayIP = ((Point)comboPoint.SelectedItem).GateWay;

            txtSubMask.Text = ((Point)comboPoint.SelectedItem).SubMask;
            txtGateway.Text = ((Point)comboPoint.SelectedItem).GateWay;

            if (string.IsNullOrEmpty(gateWayIP))
            {

            }
            else
            {
                Regex reg = new Regex(@"(\d+.\d+.\d+).\d+");


                txtIPMain.Text = reg.Match(gateWayIP).Groups[1].Value;

            }


            btnStart.Enabled = CheckSettingVailed();
        }

        //按本机ip前缀 自动筛选中心服务器
        private void txtIPMain_TextChanged(object sender, EventArgs e)
        {
            if (txtIPMain.Text.Length == 0)
            {

            }
            else
            {
                if (chkDatabase.Checked)
                {
                    txtDatabaseIP.Text = txtIPMain.Text + '.' + txtIPLast.Text;
                }
                else
                {
                    txtDatabaseIP.Text = txtIPMain.Text + '.';
                }
                string prefix = txtIPMain.Text.Substring(0, 3);
                if (prefix == "198")
                {
                    comboAppServer.DataSource = Utility.GetServersByType(Utility.ServerType.CityApp);
                    comboUpdateServer.DataSource = Utility.GetServersByType(Utility.ServerType.CityUpdate);
                }
                else
                {
                    comboAppServer.DataSource = Utility.GetServersByType(Utility.ServerType.DistrictApp);
                    comboUpdateServer.DataSource = Utility.GetServersByType(Utility.ServerType.DistrictUpdate);

                }
            }


            btnStart.Enabled = CheckSettingVailed();

        }


        /// <summary>
        /// load backup file 
        /// ip.txt point.reg
        /// </summary>
        private void LoadLocalSettings()
        {
            string pointCode;
            int distirctId;
            string hostIP;
            string subMask;
            string gateWayIP;
            string logString = string.Empty;


            //这里将会放入读取设置到界面控件的代码
            if (Utility.Setting != null)
            {

            }



            try
            {
                string[] allLines = File.ReadAllLines(@"D:\SBK\Backup\ip.txt");
                foreach (var line in allLines)
                {
                    if (line.Contains("Default Gateway"))
                    {
                        logString = "读取备份的IP信息";
                        gateWayIP = line.Replace("Default Gateway", "").Replace(". ", "").Replace(":", "").Replace(" ", "");
                        txtGateway.Text = gateWayIP;



                        distirctId = Utility.GetDistrictIdByGatewayIP(gateWayIP, out pointCode);
                        if (distirctId != -1)
                        {
                            comboDistrictsMain.SelectedValue = distirctId;
                            comboPoint.SelectedValue = pointCode;
                            txtGetooUrl.Text = Utility.GetDistricts()[distirctId-1].GetooUrl;
                            logString += " 找到匹配的网点信息。";
                        }
                        else
                        {
                            logString += " 没有找到匹配的网点信息。";
                        }

                    }
                    if (line.Contains("IP Address"))
                    {
                        hostIP = line.Replace("IP Address", "").Replace(". ", "").Replace(":", "").Replace(" ", "");
                        txtIPMain.Text = hostIP.Substring(0, hostIP.LastIndexOf('.'));
                        txtIPLast.Text = hostIP.Substring(hostIP.LastIndexOf('.') + 1);
                    }
                    if (line.Contains("Subnet Mask"))
                    {
                        subMask = line.Replace("Subnet Mask", "").Replace(". ", "").Replace(":", "").Replace(" ", "");
                        txtSubMask.Text = subMask;
                    }
                }
            }
            catch (FileNotFoundException)
            {
                logString += "没有找到备份的IP信息。";
            }
            catch (Exception ex)
            {

                logString += ex.Message;
            }


            listLog.Items.Add(logString);

            btnStart.Enabled = CheckSettingVailed();


        }

        private bool CheckSettingVailed()
        {

            Regex regex = new Regex(@"\b(?:\d{1,3}\.){3}\d{1,3}\b");
            if (!regex.Match(txtSubMask.Text).Success)
            {
                return false;
            }

            if (!regex.Match(txtGateway.Text).Success)
            {
                return false;
            }

            if (!regex.Match(txtDatabaseIP.Text).Success)
            {
                return false;
            }

            if (!regex.Match(txtIPMain.Text + "." + txtIPLast.Text).Success)
            {
                return false;
            }



            return true;

        }

        private void txtIPLast_TextChanged(object sender, EventArgs e)
        {
            btnStart.Enabled = CheckSettingVailed();
        }

        private void txtSubMask_TextChanged(object sender, EventArgs e)
        {
            btnStart.Enabled = CheckSettingVailed();
        }

        private void txtGateway_TextChanged(object sender, EventArgs e)
        {
            btnStart.Enabled = CheckSettingVailed();
        }

        private void txtDatabaseIP_TextChanged(object sender, EventArgs e)
        {
            btnStart.Enabled = CheckSettingVailed();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            if (boolIsFirstRun)
            {
                
                Utility.Setting.PointCode = txtPointCode.Text;
                Utility.Setting.IsDatabase = chkDatabase.Checked;
                Utility.Setting.IsManager = chkManager.Checked;
                Utility.Setting.LocalIp = txtIPMain.Text + '.' + txtIPLast.Text;
                Utility.Setting.SubMask = txtSubMask.Text;
                Utility.Setting.GateWay = txtGateway.Text;
                Utility.Setting.DatabaseIP = txtDatabaseIP.Text;
                Utility.Setting.AppServerIP = comboAppServer.SelectedValue.ToString();
                Utility.Setting.UpdateServerIP = comboUpdateServer.SelectedValue.ToString();
                Utility.Setting.GetooServerIP = txtGetooUrl.Text;
                comboUpdateServer.ValueMember = "Port";
                Utility.Setting.UpdateServerPort = comboUpdateServer.SelectedValue.ToString();
                Utility.SaveLocalSettings();
            }


            Dowork();
        }

        private void Dowork()
        {

            //保存网点信息到配置文件d:\sbk\settings\megasetting.DB



            //第一次运行
            if (boolIsFirstRun)
            {


                //设置防火墙端口
                listLog.Items.Add("*添加端口：\t 3306 \r\n");
                listLog.Items.Add(ExecuteShellAndGetResult("netsh.exe", "firewall add portopening tcp 3306 MySQL"));
                Application.DoEvents();

                listLog.Items.Add("*添加端口：\t 798 \r\n");
                listLog.Items.Add(ExecuteShellAndGetResult("netsh.exe", "firewall add portopening tcp 798 CA"));
                Application.DoEvents();


                //创建临时帐户
                listLog.Items.Add("*创建帐户: Manager \r\n");
                listLog.Items.Add(ExecuteShellAndGetResult("net.exe", "user Manager /add"));
                Application.DoEvents();

                listLog.Items.Add("*设置账户组 \r\n");
                listLog.Items.Add(ExecuteShellAndGetResult("net.exe", "localgroup administrators Manager /add"));
                Application.DoEvents();

                listLog.Items.Add("*设置自动登录：\tManager \r\n");
                Application.DoEvents();
                listLog.Items.Add(ExecuteShellAndGetResult("reg.exe", "add \"hklm\\software\\microsoft\\windows nt\\currentversion\\winlogon\" /v AutoAdminLogin /d 1 /f"));
                listLog.Items.Add(ExecuteShellAndGetResult("reg.exe", "add \"hklm\\software\\microsoft\\windows nt\\currentversion\\winlogon\" /v defaultusername /d Manager /f"));

                //网络配置
                SetNetworkAdapter(Utility.Setting.LocalIp, Utility.Setting.SubMask, Utility.Setting.GateWay, "", "");

                listLog.Items.Add("*重启! \r\n");
                listLog.Items.Add(ExecuteShellAndGetResult("shutdown", "-r -t 0"));
            }
            else
            {
                //第二次运行
                if (strCurrentAccountName.ToLower().IndexOf("manager") != -1)
                {
                    listLog.Items.Add("*删除临时文件夹：\tTemp \r\n");
                    Application.DoEvents();
                    listLog.Items.Add(ExecuteShellAndGetResult("cmd", "/c rmdir \"C:\\Documents and Settings\\Administrator\\Local Settings\\Temp\" /s /q"));

                    listLog.Items.Add("*移动个人文件夹到：\tD盘 \r\n");
                    Application.DoEvents();
                    listLog.Items.Add(ExecuteShellAndGetResult("xcopy", "\"C:\\Documents and Settings\\Administrator\\*.*\" \"D:\\Documents and Settings\\Administrator\\\" /e /h /y"));

                    listLog.Items.Add("*设置个人文件夹到：\tD盘 \r\n");
                    Application.DoEvents();
                    listLog.Items.Add(ExecuteShellAndGetResult("reg.exe", "add \"hklm\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\" + strAdminAccountSID + "\" /v ProfileImagePath /d \"D:\\Documents and Settings\\Administrator\" /f"));

                    listLog.Items.Add("*设置自动登录：\t Administrator \r\n");
                    Application.DoEvents();
                    listLog.Items.Add(ExecuteShellAndGetResult("reg.exe", "add \"hklm\\software\\microsoft\\windows nt\\currentversion\\winlogon\" /v defaultusername /d Administrator /f"));
                    listLog.Items.Add("*重启! \r\n");
                    listLog.Items.Add((ExecuteShellAndGetResult("shutdown", "-r -t 0")));
                }
                //第三次运行 删除临时帐户
                else if (strCurrentAccountName.ToLower().IndexOf("administrator") != -1)
                {

                    //复制网点程序
                    listLog.Items.Add("*复制网点程序: SHJZZ \r\n");

                    listLog.Items.Add(ExecuteShellAndGetResult(Application.StartupPath + "\\shjzz.exe", "/S"));
                    Application.DoEvents();

                    listLog.Items.Add("*配置网点程序：SHJZZ\r\n");
                    //txtLog .Text +=ExecuteShellAndGetResult ("reg add hklm\software\microsoft\windows\currentversion\run /v "MegaSetting" /t REG_SZ /d "%SystemDrive%\Preinstall\MegaSetting.exe")



                    RegistryKey key = Registry.LocalMachine.OpenSubKey("SOFTWARE", true);
                    key.CreateSubKey("SHJZZ");
                    key = key.OpenSubKey("SHJZZ", true);
                    key.CreateSubKey("POINT");
                    key = key.OpenSubKey("POINT", true);
                    if (Utility.Setting.IsManager)
                    {
                        key.SetValue("type", "1");
                    }
                    else
                    {
                        key.SetValue("type", "0");
                    }

                    key.CreateSubKey("D_shjzz");
                    key = key.OpenSubKey("D_shjzz", true);
                    key.SetValue("pointid", Utility.Setting.PointCode);
                    key.SetValue("pointport", "3306");
                    key.SetValue("pointserver", Utility.Setting.DatabaseIP);
                    key.SetValue("serverip", Utility.Setting.AppServerIP);
                    key.SetValue("serverport", "7001");
                    key.SetValue("countyserverip", "127.0.0.1");
                    key.SetValue("countyserverport", "8001");
                    key.SetValue("reportalertinterval", "1");
                    key.SetValue("reportinterval", "1");
                    key.SetValue("reportnumber", "10");
                    key.SetValue("uploadinterval", "1");
                    key.SetValue("uploadintervalcounty", "3");
                    key.SetValue("uploadintervalsbk", "2");
                    key.SetValue("uploadintervalsbkpic", "3");
                    key.SetValue("uploadnumber", "10");
                    key.SetValue("uploadnumbercounty", "10");
                    key.SetValue("uploadnumbersbk", "10");
                    key.SetValue("uploadnumbersbkpic", "10");

                    listLog.Items.Add("*删除启动项：\t MegaSetting \r\n");
                    Application.DoEvents();
                    listLog.Items.Add(ExecuteShellAndGetResult("reg.exe", "delete hklm\\software\\microsoft\\windows\\currentversion\\run /v \"MegaSetting\" /f"));


                    listLog.Items.Add("*删除帐户：\t Manager \r\n");
                    listLog.Items.Add(ExecuteShellAndGetResult("net.exe", "user Manager /delete"));
                    Application.DoEvents();

                    listLog.Items.Add("*删除个人文件夹：\t Manager \r\n");
                    listLog.Items.Add(ExecuteShellAndGetResult("cmd", "/c rmdir \"C:\\Documents and Settings\\Manager\" /s /q"));
                    Application.DoEvents();

                    listLog.Items.Add("*删除个人文件夹: Administrator \r\n");
                    listLog.Items.Add(ExecuteShellAndGetResult("cmd", "/c rmdir \"C:\\Documents and Settings\\Administrator\" /s /q"));
                    Application.DoEvents();

                    string strConfigString = "[config]\r\n";

                    strConfigString += "server=" + Utility.Setting.UpdateServerIP + "\r\n";

                    strConfigString += "port="+Utility.Setting.UpdateServerPort+"\r\nentry=update.update\r\n[port]\r\nIC4=1\r\nKEY=1\r\n[device]\r\nCOM1=3\r\nUSBPOS=0\r\nTYPE=3";

                    File.WriteAllText(@"d:\shjzz\client.ini", strConfigString);

                    listLog.Items.Add("*启动Getoo安装程序");
                    ExecuteShellAndGetResult("cmd", "/c start iexplore " + Utility.Setting.GetooServerIP + "getoo/getoo.application");


                    listLog.Items.Add("**全部完成!");

                    btnStart.Enabled = false;

                }

            }


        }
        private void GetEnvironments()
        {
            WindowsIdentity m_Self = WindowsIdentity.GetCurrent();
            strCurrentAccountName = m_Self.Name;

            SecurityIdentifier m_SID = m_Self.Owner;
            strCurrentAccountSID = m_SID.Value;
            ExecuteShellAndGetResult("reg.exe", "add \"hkcu\\Software\\Sysinternals\\PsGetSid\" /v EulaAccepted /t REG_DWORD /d 1 /f");

            string strAdminSID = ExecuteShellAndGetResult(Application.StartupPath + @"\psgetsid.exe", "administrator");
            strAdminAccountSID = strAdminSID.Substring(strAdminSID.IndexOf(":") + 3);
            strAdminAccountSID = strAdminAccountSID.TrimEnd(new char[] { '\r', '\n' });
            listLog.Items.Add("管理员 SID：\t" + strAdminAccountSID + "\r\n");

            string strAllUsers = ExecuteShellAndGetResult("net", "user");
            //not found manager account
            if (strAllUsers.IndexOf("Manager") == -1)
            {
                boolIsFirstRun = true;

            }
            else
            {
                boolIsFirstRun = false;
            }
        }

        static void SetNetworkAdapter(string IPAddress, string SubnetMask, string GatewayIP, string MainDNSIP, string SubDNSIP)
        {
            ManagementBaseObject inPar = null;
            ManagementBaseObject outPar = null;
            ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
            ManagementObjectCollection moc = mc.GetInstances();
            foreach (ManagementObject mo in moc)
            {
                if (!(bool)mo["IPEnabled"])
                    continue;

                //设置ip地址和子网掩码 
                inPar = mo.GetMethodParameters("EnableStatic");
                inPar["IPAddress"] = new string[] { IPAddress };// 1.备用 2.IP
                inPar["SubnetMask"] = new string[] { SubnetMask };
                outPar = mo.InvokeMethod("EnableStatic", inPar, null);

                //设置网关地址 
                inPar = mo.GetMethodParameters("SetGateways");
                inPar["DefaultIPGateway"] = new string[] { GatewayIP }; // 1.网关;2.备用网关
                outPar = mo.InvokeMethod("SetGateways", inPar, null);

                //设置DNS 
                inPar = mo.GetMethodParameters("SetDNSServerSearchOrder");
                inPar["DNSServerSearchOrder"] = new string[] { MainDNSIP, SubDNSIP }; // 1.DNS 2.备用DNS
                outPar = mo.InvokeMethod("SetDNSServerSearchOrder", inPar, null);
                break;
            }
        }

        private string ExecuteShellAndGetResult(string filename, string arguments)
        {
            //实例化一个进程类
            Process cmd = new Process();
            string ret;

            cmd.StartInfo.FileName = filename;
            cmd.StartInfo.Arguments = arguments;

            //将cmd的标准输入和输出全部重定向到.NET的程序里

            cmd.StartInfo.UseShellExecute = false; //此处必须为false否则引发异常

            cmd.StartInfo.RedirectStandardInput = true; //标准输入
            cmd.StartInfo.RedirectStandardOutput = true; //标准输出

            //不显示命令行窗口界面
            cmd.StartInfo.CreateNoWindow = true;
            cmd.StartInfo.WindowStyle = ProcessWindowStyle.Normal;

            cmd.Start(); //启动进程

            //获取输出
            //需要说明的：\t此处是指明开始获取，要获取的内容，
            //只有等进程退出后才能真正拿到
            ret = cmd.StandardOutput.ReadToEnd();

            cmd.WaitForExit();//等待控制台程序执行完成
            cmd.Close();//关闭该进程

            return ret;
        }

        private void chkManager_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void panelPointSetting_Paint(object sender, PaintEventArgs e)
        {

        }
    }

}
